home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / MacHaskell 2.2 / progs / lib / hbc / Native.hs < prev    next >
Encoding:
Text File  |  1994-09-27  |  6.6 KB  |  264 lines  |  [TEXT/YHS2]

  1. -- Native.hs -- native data conversions and I/O
  2. --
  3. -- author :  Sandra Loosemore
  4. -- date   :  07 Jun 1994
  5. --
  6. --
  7. -- Unlike in the original hbc version of this library, a Byte is a completely
  8. -- abstract data type and not a character.  You can't read and write Bytes
  9. -- to ordinary text files; you must use the operations defined here on
  10. -- Native files.
  11. -- It's guaranteed to be more efficient to read and write objects directly
  12. -- to a file than to do the conversion to a Byte stream and read/write
  13. -- the Byte stream.
  14.  
  15.  
  16. module Native where
  17.  
  18. import NativePrims
  19.  
  20.  
  21. -- these data types are completely opaque on the Haskell side.
  22.  
  23. data Byte = Byte
  24. data ByteFile = ByteFile
  25. type Bytes = [Byte]
  26.  
  27. instance Text(Byte) where
  28.  showsPrec _ _ = showString "Byte"
  29.  
  30. instance Text(ByteFile) where
  31.  showsPrec _ _ = showString "ByteFile"
  32.  
  33.  
  34. -- Byte file primitives
  35.  
  36. openInputByteFile    :: String -> IO (ByteFile)
  37. openOutputByteFile    :: String -> IO (ByteFile)
  38. closeByteFile        :: ByteFile -> IO ()
  39.  
  40. openInputByteFile    = primOpenInputByteFile
  41. openOutputByteFile    = primOpenOutputByteFile
  42. closeByteFile        = primCloseByteFile
  43.  
  44.  
  45. -- Here are the basic operations defined on the class.
  46.  
  47. class Native a where
  48.  
  49.   -- these are primitives
  50.   showBytes        :: a -> Bytes -> Bytes
  51.   readBytes        :: Bytes -> Maybe (a, Bytes)
  52.   showByteFile        :: a -> ByteFile -> IO ()
  53.   readByteFile        :: ByteFile -> IO (Maybe a)
  54.  
  55.   -- these are derived
  56.   listShowBytes        :: [a] -> Bytes -> Bytes
  57.   listReadBytes        :: Int -> Bytes -> Maybe ([a], Bytes)
  58.   listShowByteFile      :: [a] -> ByteFile -> IO ()
  59.   listReadByteFile    :: Int -> ByteFile -> IO (Maybe [a])
  60.  
  61.  
  62.   -- here are defaults for the derived methods.
  63.   
  64.   listShowBytes l bytes = foldr showBytes bytes l
  65.  
  66.   listReadBytes 0 bytes =
  67.     Just ([], bytes)
  68.   listReadBytes n bytes =
  69.     case (readBytes bytes) of
  70.       Just (head, bytes1) ->
  71.         case (listReadBytes (n - 1) bytes1) of
  72.           Just (tail, bytes2) -> Just (head:tail, bytes2)
  73.       Nothing -> Nothing
  74.       Nothing -> Nothing
  75.  
  76.  
  77.   listShowByteFile l f =
  78.     foldr (\ head tail -> (showByteFile head f) >> tail)
  79.           (return ())
  80.       l
  81.  
  82.   listReadByteFile 0 f =
  83.     return (Just [])
  84.   listReadByteFile n f =
  85.     (readByteFile f) >>= 
  86.     (\ result1 ->
  87.       case result1 of
  88.         Just head ->
  89.       (listReadByteFile (n - 1) f) >>=
  90.          (\ result2 ->
  91.           case result2 of
  92.             Just tail -> return (Just (head : tail))
  93.             Nothing -> return Nothing)
  94.         Nothing -> return Nothing)
  95.  
  96.  
  97. -- Basic instances, defined as primitives
  98.  
  99. instance Native Char where
  100.   showBytes        = primCharShowBytes
  101.   readBytes        = primCharReadBytes
  102.   showByteFile        = primCharShowByteFile
  103.   readByteFile        = primCharReadByteFile
  104.  
  105. instance Native Int where
  106.   showBytes        = primIntShowBytes
  107.   readBytes        = primIntReadBytes
  108.   showByteFile        = primIntShowByteFile
  109.   readByteFile        = primIntReadByteFile
  110.  
  111. instance Native Float where
  112.   showBytes        = primFloatShowBytes
  113.   readBytes        = primFloatReadBytes
  114.   showByteFile        = primFloatShowByteFile
  115.   readByteFile        = primFloatReadByteFile
  116.  
  117. instance Native Double where
  118.   showBytes        = primDoubleShowBytes
  119.   readBytes        = primDoubleReadBytes
  120.   showByteFile        = primDoubleShowByteFile
  121.   readByteFile        = primDoubleReadByteFile
  122.  
  123.  
  124. -- Byte instances, so you can write Bytes to a ByteFile
  125.  
  126. instance Native Byte where
  127.   showBytes        = (:)
  128.   readBytes l =
  129.     case l of
  130.       []  -> Nothing
  131.       h:t -> Just(h,t)
  132.   showByteFile        = primByteShowByteFile
  133.   readByteFile        = primByteReadByteFile
  134.  
  135.  
  136. -- 2-tuple instances
  137.  
  138. instance (Native a, Native b) => Native (a,b) where
  139.  
  140.   showBytes (a,b) bytes = showBytes a (showBytes b bytes)
  141.  
  142.   readBytes bytes = 
  143.     case (readBytes bytes) of
  144.       Just (a, bytes1) ->
  145.         case (readBytes bytes1) of
  146.           Just (b, bytes2) -> Just ((a,b), bytes2)
  147.           Nothing -> Nothing
  148.       Nothing -> Nothing
  149.  
  150.   showByteFile (a,b) f = (showByteFile a f) >> (showByteFile b f)
  151.  
  152.   readByteFile f =
  153.     (readByteFile f) >>=
  154.     (\ result1 ->
  155.       case result1 of
  156.         Just a ->
  157.           (readByteFile f) >>=
  158.       (\ result2 ->
  159.         case result2 of
  160.           Just b -> return (Just (a,b))
  161.           Nothing -> return Nothing)
  162.         Nothing -> return Nothing)
  163.  
  164.  
  165. -- 3-tuple instances
  166.  
  167. instance (Native a, Native b, Native c) => Native (a,b,c) where
  168.  
  169.   showBytes (a,b,c) bytes = showBytes a (showBytes b (showBytes c bytes))
  170.  
  171.   readBytes bytes = 
  172.     case (readBytes bytes) of
  173.       Just (a, bytes1) ->
  174.         case (readBytes bytes1) of
  175.           Just (b, bytes2) ->
  176.         case (readBytes bytes2) of
  177.           Just (c, bytes3) -> Just ((a,b,c), bytes3)
  178.           Nothing -> Nothing
  179.           Nothing -> Nothing
  180.       Nothing -> Nothing
  181.  
  182.   showByteFile (a,b,c) f =
  183.     (showByteFile a f) >>
  184.     (showByteFile b f) >>
  185.     (showByteFile c f)
  186.  
  187.   readByteFile f =
  188.     (readByteFile f) >>=
  189.     (\ result1 ->
  190.       case result1 of
  191.         Just a ->
  192.           (readByteFile f) >>=
  193.       (\ result2 ->
  194.         case result2 of
  195.           Just b ->
  196.             (readByteFile f) >>=
  197.         (\ result3 ->
  198.               case result3 of
  199.             Just c -> return (Just (a,b,c))
  200.             Nothing -> return Nothing)
  201.           Nothing -> return Nothing)
  202.         Nothing -> return Nothing)
  203.  
  204.  
  205. -- List instances, written as a count followed by contents of the list
  206.  
  207. instance (Native a) => Native[a] where
  208.  
  209.   showBytes l bytes = showBytes (length l) (listShowBytes l bytes)
  210.  
  211.   readBytes bytes = 
  212.     case (readBytes bytes) of
  213.       Just (n, bytes1) -> listReadBytes n bytes1
  214.       Nothing -> Nothing
  215.  
  216.   showByteFile l f = (showByteFile (length l) f) >> (listShowByteFile l f)
  217.  
  218.   readByteFile f =
  219.     (readByteFile f) >>=
  220.     (\ result1 ->
  221.       case result1 of
  222.         Just n -> listReadByteFile n f
  223.     Nothing -> return Nothing)
  224.  
  225.  
  226.  
  227. -- These functions are like the primIntxx but use a "short" rather than
  228. -- "int" representation.
  229.  
  230. shortIntToBytes        :: Int -> Bytes -> Bytes
  231. bytesToShortInt        :: Bytes-> Maybe(Int,Bytes)
  232. shortIntToByteFile    :: Int -> ByteFile -> IO ()
  233. bytesToShortIntIO       :: ByteFile -> IO (Maybe Int)
  234.  
  235. shortIntToBytes        = primShortShowBytes
  236. bytesToShortInt     = primShortReadBytes
  237. shortIntToByteFile    = primShortShowByteFile
  238. bytesToShortIntIO     = primShortReadByteFile
  239.  
  240.  
  241. -- simplified interfaces
  242.  
  243. showB :: (Native a) =>  a -> Bytes
  244. showB x = showBytes x []
  245.  
  246. readB :: (Native a) => Bytes -> a
  247. readB bytes = case (readBytes bytes) of
  248.                 Just (x, _) -> x
  249.         _ -> error "readBytes failed"
  250.  
  251.  
  252. readBFile :: String -> IO(Bytes)
  253. readBFile name =
  254.   openInputByteFile name >>= \ f ->
  255.   readBytesFromByteFile f
  256.  
  257. readBytesFromByteFile :: ByteFile -> IO(Bytes)
  258. readBytesFromByteFile f =
  259.   primByteReadByteFile f >>= \ result1 ->
  260.   case result1 of
  261.     Just head -> readBytesFromByteFile f >>= \ tail ->
  262.                  return (head:tail)
  263.     Nothing -> closeByteFile f >> return ([])
  264.